﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EzDesk.Attendance.AttendanceImpl;
using EzDesk.Attendance.Model;

namespace EzDesk.Attendance.AttendanceImpl.Repositories
{
    public class AttendanceRepository
    {
        #region [ 构造器 ] 
        private EzDeskAttendanceDataContext _db;

        public AttendanceRepository(EzDeskAttendanceDataContext db)
        {
            this._db = db;
        }

        // todo: 使用DI重构
        public AttendanceRepository()
            :this(new EzDeskAttendanceDataContext())
        {
        }
        #endregion

        public void SaveChanges()
        {
            _db.SubmitChanges();
        }


        #region [ 法定节假日数据 - LegalHoliday ]
        /// <summary>
        /// 取得某一天的法定假日信息
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public LegalHoliday GetLegalHolidayInfo(DateTime date)
        {
            return (from l in _db.ez_LegalHolidays
                    where l.StartDay <= date && date <= l.EndDay
                    select new LegalHoliday()
                    {
                        HolidayId = l.HolidayId,
                        StartDate = l.StartDay,
                        EndDate = l.EndDay,
                        Name = l.HolidayName,
                    }).FirstOrDefault();
        }

        #endregion

        #region [ 调休状态 - ExtraShift ]
        /// <summary>
        /// 取得某一天的调休状态
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public ExtraShift GetExtraShiftInfo(DateTime date)
        {
            return (from e in _db.ez_ExtraShifts
                    where e.StartDay <= date && date <= e.EndDay
                    select new ExtraShift()
                    {
                        ExtraShiftId = e.ExtraShiftId,
                        Name = e.ShiftName,
                        StartDate = e.StartDay,
                        EndDate = e.EndDay,
                        NeedToWork = e.NeedWork,
                    }).FirstOrDefault();
        }
        #endregion

        #region [ 考勤记录相关 ]

        public IQueryable<AttendanceInfo> GetAttendanceInfos()
        {
            return from a in _db.ez_AttendanceInfos
                   select new AttendanceInfo()
                   {
                       Id = a.AttendanceId,
                       ActionTime = a.ActionTime,
                       DutyType = (DutyTypeEnum)a.DutyType,
                       Day = a.Day,
                       Explanation = a.Explanation,
                       UserId = a.UserId,
                       IsExtraWork = a.IsExtraWork,
                   };
        }

        public void CreateAttendanceInfo(AttendanceInfo newAttendanceInfo, bool saveChanges = true)
        {
            var attendance = new ez_AttendanceInfo()
            {
                AttendanceId = newAttendanceInfo.Id,
                UserId = newAttendanceInfo.UserId,
                DutyType = (int)newAttendanceInfo.DutyType,
                Day = DateTime.Today,
                Explanation = null,
            };

            _db.ez_AttendanceInfos.InsertOnSubmit(attendance);

            if (saveChanges)
            {
                SaveChanges();
            }
        }

        public void UpdateAttendanceInfo(AttendanceInfo model, bool saveChanges = true)
        {
            var attendanceInfo = _db.ez_AttendanceInfos.Where(p =>
                model.Id == p.AttendanceId &&
                model.UserId == p.UserId &&
                model.Day == p.Day &&
                (int)model.DutyType == p.DutyType
                ).SingleOrDefault();

            if (attendanceInfo == null)
            {
                throw new Exception("AttendanceInfo Not Found!");
            }

            attendanceInfo.ActionTime = model.ActionTime;
            attendanceInfo.Explanation = model.Explanation;
            attendanceInfo.Day = model.Day;

            if (saveChanges)
            {
                SaveChanges();
            }
        }

        #endregion

        #region [ 休假 - LeaveInfo ]

        public IQueryable<LeaveType> GetLeaveTypes()
        {
            return _db.ez_LeaveTypes.Select(
                p => new LeaveType()
                {
                    LeaveTypeId = p.LeaveTypeId,
                    LeaveTypeName = p.LeaveName,
                    IsForWork = p.IsForWork,
                }
            );
        }


        /// <summary>
        /// 找出所有休假信息
        /// </summary>
        /// <param name="userIdStr"></param>
        /// <param name="day"></param>
        /// <returns></returns>
        public IQueryable<LeaveInfo> GetAllLeaveInfo()
        {
            return from l in _db.ez_LeaveInfos
                   select new LeaveInfo()
                   {
                       LeaveId = l.LeaveId,
                       LeaveTypeId = l.LeaveTypeId,
                       LeaveTypeName = l.LeaveTypeName,
                       StartTime = l.StartTime,
                       EndTime = l.EndTime,
                       IsAudited = l.IsAudited,
                       AuditNote = l.AuditNote,
                       Description = l.Description,
                       IsForWork = l.ez_LeaveType.IsForWork,
                       AuditUserId = l.AuditUserId.GetValueOrDefault(Guid.Empty),
                       AuditUserName = l.AuditUserName,
                       AuditTime = l.AuditTime.GetValueOrDefault(DateTime.Now),
                       UserId = l.UserId,
                       UserName = l.UserName,
                   };
        }

        public void CreateLeaveInfo(LeaveInfo model, bool saveChanges = true)
        {
            _db.ez_LeaveInfos.InsertOnSubmit(
                new ez_LeaveInfo()
                {
                    LeaveId = model.LeaveId,
                    Description = model.Description,


                    LeaveTypeName = model.LeaveTypeName,
                    LeaveTypeId = model.LeaveTypeId,

                    StartTime = model.StartTime,
                    EndTime = model.EndTime,
                    UserId = model.UserId,
                    UserName = model.UserName,

                    IsAudited = model.IsAudited,
                    AuditUserId = model.AuditUserId,
                    AuditNote = model.AuditNote,
                    AuditUserName = model.AuditUserName,
                    AuditTime = DateTime.Now,
                }
                );
            if (saveChanges)
            {
                SaveChanges();
            }
        }

        public void UpdateLeaveInfo(LeaveInfo model, bool saveChanges = true)
        {
            var leaveToUpdate = _db.ez_LeaveInfos.Where(p => p.LeaveId == model.LeaveId).FirstOrDefault();

            leaveToUpdate.StartTime = model.StartTime;
            leaveToUpdate.EndTime = model.EndTime;
            leaveToUpdate.Description = model.Description;

            leaveToUpdate.IsAudited = model.IsAudited;
            leaveToUpdate.AuditUserName = model.AuditUserName;
            leaveToUpdate.AuditUserId = model.AuditUserId;
            leaveToUpdate.AuditNote = model.AuditNote;
            leaveToUpdate.AuditTime = model.AuditTime;

            if (saveChanges)
            {
                this.SaveChanges();
            }
        }




        public void RemoveLeaveInfo(Guid leaveId)
        {
            var leaveInfoToRemove = _db.ez_LeaveInfos.Where(p => p.LeaveId == leaveId).FirstOrDefault();
            _db.ez_LeaveInfos.DeleteOnSubmit(leaveInfoToRemove);
            _db.SubmitChanges();
        }
        #endregion

        #region [ 自定义调休 - CustomizedShiftWorks ]

        public IQueryable<CustomizedShiftWork> GetCustomizedShiftWorks()
        {
            return from c in _db.ez_CustomizedShiftWorks
                   select new CustomizedShiftWork()
                   {
                       UserId = c.UserId,
                       Day = c.Day,
                       AuditedUserId = c.AuditedUserId,
                       CustomizedShitWorkMiniute = c.CustomizedShiftWorkMiniutes,
                       Explaination = c.Explaination,
                   };
        }


        public void CreateCustomizedShiftWork(CustomizedShiftWork customizedShiftWork, bool saveChanges = true)
        {
            _db.ez_CustomizedShiftWorks.InsertOnSubmit(
                new ez_CustomizedShiftWork()
                {
                    UserId = customizedShiftWork.UserId,
                    Day = customizedShiftWork.Day,
                    AuditedUserId = customizedShiftWork.AuditedUserId,
                    CustomizedShiftWorkMiniutes = customizedShiftWork.CustomizedShitWorkMiniute,
                    Explaination = customizedShiftWork.Explaination,
                }
                );

            if (saveChanges)
            {
                SaveChanges();
            }
        }





        public void UpdateCustomizedShiftWork(CustomizedShiftWork customizedShiftWork, bool saveChanges = true)
        {
            var existShiftWork = _db.ez_CustomizedShiftWorks.Where(p =>
                p.UserId == customizedShiftWork.UserId &&
                p.Day == customizedShiftWork.Day
                ).SingleOrDefault();

            if (existShiftWork != null)
            {
                existShiftWork.AuditedUserId = customizedShiftWork.AuditedUserId;
                existShiftWork.CustomizedShiftWorkMiniutes = customizedShiftWork.CustomizedShitWorkMiniute;
                existShiftWork.Explaination = customizedShiftWork.Explaination;

                if (saveChanges)
                {
                    SaveChanges();
                }
            }
        }
        #endregion

        #region [ 加班申请相关 - ExtraWork ]
        public bool IsExtraWorkApplyed(ExtraWorkApplication application)
        {
            var extrawork = _db.ez_Person_ExtraWorks
                .Where(p => p.UserId == application.UserId && p.Day == application.Day)
                .SingleOrDefault();
            return extrawork != null;
        }

        public void AddExtraWorkApplication(ExtraWorkApplication application, bool saveChanges = true)
        {
            var extrawork = _db.ez_Person_ExtraWorks
                .Where(p => p.UserId == application.UserId && p.Day == application.Day)
                .SingleOrDefault();
            if (extrawork == null)
            {
                _db.ez_Person_ExtraWorks.InsertOnSubmit(
                    new ez_Person_ExtraWork()
                    {
                        UserId = application.UserId,
                        Day = application.Day,
                    }
                    );
                if (saveChanges)
                {
                    this.SaveChanges();
                }
            }
        }

        public void RemoveExtraWorkAppliaction(ExtraWorkApplication application, bool saveChanges = true)
        {
            var extrawork = _db.ez_Person_ExtraWorks
                .Where(p => p.UserId == application.UserId && p.Day == application.Day)
                .SingleOrDefault();
            if (extrawork != null)
            {
                _db.ez_Person_ExtraWorks.DeleteOnSubmit(extrawork);
                if (saveChanges)
                {
                    this.SaveChanges();
                }
            }
        }
        #endregion
    }
}